package com.grandstream.website.app.security.authorize;

import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;

import javax.sql.DataSource;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.access.method.AbstractMethodSecurityMetadataSource;
import org.springframework.security.web.util.UrlMatcher;

import com.grandstream.website.app.security.enums.EmDbResourcetype;

/**  
 * 
 * 类描述：  
 * 创建人：Smile_zheng
  
 * 创建时间：2010-12-8 上午07:58:03  
 * 修改人：Smile_Zheng 
 * 修改时间：2010-12-8 上午07:58:03  
 * 修改备注：  
 * @version v 1.0
 *   
 */
public class DbMethodFilterInvocationMetadataSource extends  AbstractMethodSecurityMetadataSource{
	public static final String DEFAULT_ROLE_RESC_URL_QUERY="select role.name,resc.rule from sys_resource resc ,sys_role role ,sys_role_resc role_resc " +
			"where resc.sysid =role_resc.resourceid and role.sysid=role_resc.roleid and resc.type='"+EmDbResourcetype.METHOD+"' " +
					"and resc.status='1' and role.status='1' and role_resc.status='1' order by resc.priority";
	
	private String role_resc_url_query;
	
	private JdbcTemplate jdbcTemplate;
	
	private UrlMatcher urlMatcher;
	
	public UrlMatcher getUrlMatcher() {
		return urlMatcher;
	}


	public void setUrlMatcher(UrlMatcher urlMatcher) {
		this.urlMatcher = urlMatcher;
	}


	public DbMethodFilterInvocationMetadataSource(){
		role_resc_url_query=DEFAULT_ROLE_RESC_URL_QUERY;
	}

	
	public java.util.List<Resource> getResourceList(){
		return jdbcTemplate.query(role_resc_url_query, new RowMapper<Resource>() {
				public Resource mapRow(ResultSet rs, int rowNum) throws SQLException {
					// TODO Auto-generated method stub
					Resource resource =new Resource();
					resource.rolename=rs.getString(1);
					resource.rule=rs.getString(2);
					return resource;
				}
			});
	}
	
	
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate=new JdbcTemplate(dataSource);
	}
	public String getRole_resc_url_query() {
		return role_resc_url_query;
	}
	public void setRole_resc_url_query(String role_resc_url_query) {
		this.role_resc_url_query = role_resc_url_query;
	}
	
	/* (non-Javadoc)  
	* @see org.springframework.security.access.SecurityMetadataSource#getAttributes(java.lang.Object)  
	*/
	
	/* (non-Javadoc)  
	* @see org.springframework.security.access.SecurityMetadataSource#getAllConfigAttributes()  
	*/
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		// TODO Auto-generated method stub
		return null;
	}

	/* (non-Javadoc)  
	* @see org.springframework.security.access.SecurityMetadataSource#supports(java.lang.Class)  
	*/

	private  class Resource{
		private String rolename;
		private String rule;
	}
	/* (non-Javadoc)  
	* @see org.springframework.security.access.method.MethodSecurityMetadataSource#getAttributes(java.lang.reflect.Method, java.lang.Class)  
	*/

	/* (non-Javadoc)  
	* @see org.springframework.security.access.method.MethodSecurityMetadataSource#getAttributes(java.lang.reflect.Method, java.lang.Class)  
	*/
	public Collection<ConfigAttribute> getAttributes(Method method,
			Class<?> targetClass) {
		// TODO Auto-generated method stub
		String methodName=(targetClass.getName()+"."+method.getName()).toLowerCase().trim();
		Collection<ConfigAttribute> ret=null;
		java.util.List<Resource> ResourceList= getResourceList();
		if(targetClass ==null ){
			 return null;
		 }
		return findAttributesSpecifiedAgainst(ResourceList,method,targetClass);
	}
	
	public   Collection<ConfigAttribute>  findAttributesSpecifiedAgainst(java.util.List<Resource> ResourceList,Method method,Class<?> targetClass){
		String methodName=(targetClass.getName()+"."+method.getName()).toLowerCase().trim();
		 for(Resource res :ResourceList){
	        	String resurl =res.rule==null?null:res.rule.toLowerCase().trim();
	        	boolean matched = urlMatcher.pathMatchesUrl(resurl, methodName);
	        	if(matched){
	        		Collection<ConfigAttribute> collection= new ArrayList();
	        		collection.add(new SecurityConfig(res.rolename));
	        		return collection;
	        	}
	        }
		if(targetClass.getSuperclass()!=null){
			return findAttributesSpecifiedAgainst(ResourceList,method,targetClass.getSuperclass());
		}
		return null;
	}
	 
}
